iT邦幫忙

2024 iThome 鐵人賽

DAY 24
0
Modern Web

前後端整合,用Spring boot 與React 開發屬於自己的記帳網頁系列 第 26

Day26 Java Srping boot 後端安全管理:Spring boot Security介紹

  • 分享至 

  • xImage
  •  

前言

對於網頁開發來說,除了前後端開發之外,資料的安全性也是很重要的一塊。
因為只有三十天的時間,我們並沒有辦法把所有的技術都分享給大家,但我們可以把幾個重要的觀念實作出來,讓大家可以跟著學習,當大家學會這些基本的觀念之後,再往下就會了解更多,變得更好。
所以接下來最後,我們把網路的安全性的部分也交給大家

Spring boot Security介紹

基本上,Spring boot Security包山包海,甚麼功能都有,我們這次只是來實作一小部分
Spring Boot Security 是 Spring Framework 的其中一個模組,用於簡化和加強應用程序的安全性。
它提供了大量的預設功能來保護應用程序免受常見的安全威脅,例如跨站點請求偽造(CSRF)、會話劫持和 SQL 注入。Spring Security 是一個靈活且可擴展的安全框架,能夠適應各種應用場景,無論是傳統的 Web 應用還是現代化的 REST API。

使用 Spring Boot Security的好處

現代應用程序的安全性要求非常高,特別是在敏感數據(例如用戶信息或金融數據)需要被保護的情況下。許多開發者試圖自己實現安全機制,但這往往會導致漏洞和不一致的行為。而 Spring Boot Security 為我們提供了一套經過廣泛測試的解決方案,能夠幫助我們避免常見的安全問題。這些問題包括:

  • 用戶身份驗證(Authentication):確保只有合法的用戶能夠訪問應用。
  • 授權(Authorization):確保用戶只能執行被允許的操作。
  • 防止跨站點腳本攻擊(XSS)、跨站請求偽造(CSRF)和 SQL 注入等安全威脅。
    Spring Boot Security 讓開發者能夠在應用中輕鬆實現這些功能,從而更快地上線應用,並同時保持高水準的安全性。

Spring Security的簡單基本概念

身份驗證(Authentication)

身份驗證的目的是確定應用中的用戶是誰。在 Spring Security 中,這通常是通過使用帳戶名和密碼來進行。當用戶提交其憑據時,Spring Security 將驗證這些憑據的合法性,並生成一個 Authentication 對象,這個對象代表當前已驗證的用戶。
Spring Security 支持多種身份驗證方法,包括:

  • 基於數據庫的身份驗證:從數據庫中讀取用戶信息進行驗證。
  • LDAP(輕量級目錄訪問協定)驗證:與 LDAP 服務器進行交互來驗證用戶。
  • OAuth2 和 OpenID Connect:允許應用通過第三方身份提供者(例如 Google、Facebook)進行身份驗證。

授權(Authorization)

授權是指確保已經通過身份驗證的用戶只能執行他們有權限執行的操作。Spring Security 通過使用角色和權限來實現授權。每個用戶都可以被賦予一個或多個角色,這些角色代表用戶的權限集合。
例如,一個系統可能有以下角色:

  • ROLE_USER:普通用戶,允許查看資料和進行基本操作。
  • ROLE_ADMIN:管理員,允許進行增刪改等高級操作。
    開發者可以通過 Spring Security 的注解或配置來控制哪些 URL 或方法只有某些角色的用戶可以訪問。

Spring Boot Security 的基本配置

在 Spring Boot 中啟用 Spring Security 十分簡單。通過引入 spring-boot-starter-security 依賴,Spring Boot 會自動配置一個基礎的安全配置,這包括基本的身份驗證和授權功能。
以下是一個基本的 Spring Boot Security 配置:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

當應用啟動後,Spring Security 會自動為應用提供一個默認的登錄頁面,並且要求用戶通過身份驗證才能訪問任何受保護的資源。
如果我們希望定制這些行為,可以通過創建一個配置類來擴展 Spring Security 的默認配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/public/**").permitAll()  // 公共路徑允許所有訪問
            .anyRequest().authenticated()  // 其他路徑需要身份驗證
            .and()
            .formLogin()  // 啟用表單登錄
            .loginPage("/login")  // 自定義登錄頁面
            .permitAll();
    }
}

自定義身份驗證

在實際應用中,我們通常需要自定義身份驗證邏輯,例如從數據庫中獲取用戶信息或集成第三方身份驗證系統。Spring Security 支持我們使用 UserDetailsService 接口來實現自定義的身份驗證邏輯。
例如,我們可以創建一個自定義的 UserDetailsService 來從數據庫加載用戶信息:

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found");
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());
    }
}

這樣,我們可以在 SecurityConfig 中註冊這個 UserDetailsService:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());
}

密碼加密

安全地存儲用戶密碼是非常重要的。Spring Security 提供了多種加密算法,我們可以使用 PasswordEncoder 接口來對密碼進行加密和驗證。
Spring Security 常用的加密算法包括:

  • BCryptPasswordEncoder:使用 BCrypt 算法加密密碼。
  • SCryptPasswordEncoder:使用 SCrypt 算法加密密碼。
    我們可以在配置中定義密碼加密方式:
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

CSRF 保護

Spring Security 默認啟用了跨站請求偽造(CSRF)保護。CSRF 是一種攻擊,它試圖通過冒充已驗證用戶的請求來對應用進行未授權操作。Spring Security 通過生成一個唯一的 CSRF token 並在每個表單中包含該 token 來防止這類攻擊。
在某些情況下,我們可能需要禁用 CSRF 保護,特別是在開發 REST API 時。可以通過以下配置禁用 CSRF:

http.csrf().disable();

基於 JWT 的安全性

對於現代化的應用,特別是 REST API,JWT(JSON Web Token)已經成為一種流行的身份驗證方式。Spring Security 允許我們使用 JWT 來保護 API。當用戶登錄後,服務器生成一個 JWT 並返回給客戶端。客戶端在後續的請求中包含該 token,服務器則通過驗證這個 token 來確認用戶的身份。
一個典型的 JWT 安全實現包括以下步驟:

  1. 用戶提交憑據,服務器驗證後生成 JWT。
  2. 客戶端在後續請求的 Authorization 標頭中包含該 JWT。
  3. 服務器通過一個過濾器攔截請求並驗證 JWT。
    以下是一個簡單的 JWT 過濾器實現:

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String token = request.getHeader("Authorization");
        if (token != null && validateToken(token)) {
            SecurityContextHolder.getContext().setAuthentication(getAuthentication(token));
        }
        filterChain.doFilter(request, response);
    }
}

結論

Spring Boot Security 是一個強大且靈活的框架,能夠滿足各種應用的安全需求。
我們這三十天的目標,就是設置SCRF的安全性,然後建立User跟Admin帳密,用前端輸入帳密來控制後端,這次就先跳過JWT的教學,有興趣的夥伴可以自己從網路上尋找其他資源。
那麼,今天我們大致上瞭解了Spring boot Security的關念,明天,就讓我們來實作吧!


上一篇
Day25 React前端開發-使用Charts顯示成果
下一篇
Day27 Spring boot Security - 設置Security Config& CSRF
系列文
前後端整合,用Spring boot 與React 開發屬於自己的記帳網頁30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言